#include <iostream>
#include <csignal>
#include <opencv2/opencv.hpp>
// 未实现功能。。。
bool is_running = true;

void OnSignal(int)
{
    is_running = false;
}

int main()
{
    // 触发下面的信号就退出
    signal(SIGINT, OnSignal);
    signal(SIGQUIT, OnSignal);
    signal(SIGTERM, OnSignal);

    // 打开摄像头
    cv::VideoCapture capture("/dev/video0");
    if (!capture.isOpened())
    {
        std::cerr << "Failed to open camera." << std::endl;
        return EXIT_FAILURE;
    }
    capture.set(cv::CAP_PROP_FRAME_WIDTH, 640);
    capture.set(cv::CAP_PROP_FRAME_HEIGHT, 480);

//    std::string rtmp_server_url = "rtmp://124.221.6.242:1935/live/rtmp";

    std::stringstream command;
    command << "ffmpeg ";


    // infile options
    command << "-y "               // 覆盖输出文件
        << "-an "              // 禁用音频
        << "-f rawvideo "      // 强制将格式转换为rawvideo
        << "-vcodec rawvideo " // 强制视频rawvideo（“复制”到复制流）
        << "-pix_fmt bgr24 "   // 将像素格式设置为bgr24
        << "-s 640x480 "       // 设置帧大小为640x480
        << "-c:v libx264"      // 使用libx264编码器进行视频编码
        << "-tune zerolatency"// 调整编码器以减少延迟
        << "-f flv"            // 将格式强制为flv
        << "-preset veryfast"
        << "-r 10 "          // 设置帧速率为100 FPS
        << "-i - "
      //  << "rtmp://124.221.6.242:1935/live/rtmp";
        << "rtmp://192.168.31.229:1935/live/rtmp";



    std::cout << "------------command:" << command.str() << std::endl;

    cv::Mat frame;

    // 在子进程中调用 ffmpeg 进行推流
    FILE *fp = nullptr;
    fp = popen(command.str().c_str(), "w");

    // 将 cv 读到的每一帧传入子进程
    if (fp != nullptr)
    {
        while (is_running)
        {
            capture >> frame;
            if (frame.empty())
            {
                std::cerr << "Captured an empty frame." << std::endl;
                continue;
            }

            size_t frame_size = frame.total() * frame.elemSize();
            std::cout << "Frame size: " << frame_size << std::endl;
            size_t bytes_written = fwrite(frame.data, sizeof(char), frame_size, fp);
            std::cout << "Bytes written: " << bytes_written << std::endl;
            if (bytes_written != frame_size)
            {
                std::cerr << "Error writing frame data to ffmpeg." << std::endl;
            }


            //fwrite(frame.data, sizeof(char), frame.total() * frame.elemSize(), fp);
        }
        pclose(fp);
        return EXIT_SUCCESS;
    }
    else
    {
         std::cerr << "Failed to open pipe to ffmpeg." << std::endl;
        return EXIT_FAILURE;
    }
}

